package sg.edu.nus.iss.billing.dao.customer;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import sg.edu.nus.iss.billing.common.DbUtil;
import sg.edu.nus.iss.billing.common.Util;
import sg.edu.nus.iss.billing.common.exception.BadDaoCallException;
import sg.edu.nus.iss.billing.common.exception.BadDbCallException;
import sg.edu.nus.iss.billing.common.exception.InvalidParamsException;
import sg.edu.nus.iss.billing.vo.customer.CustomerComplaintVO;

/**
 * @author Chee Ann
 *
 */
public class ComplaintsDAO implements ICustomerComplaintsDAO {
	
	private ArrayList<String> data = null;
	public static final String FILE_PATH = "data//complaint.txt";
	
	public ComplaintsDAO() {
		try {
			data = (ArrayList<String>) DbUtil.loadDb(FILE_PATH);
		} catch (BadDbCallException e) {
			data = new ArrayList<String>(); // Assume empty database.
			e.printStackTrace();
		}
	}
	
	private void CreateComplaint(CustomerComplaintVO complaint) throws BadDaoCallException{
		if (ComplaintExist(complaint.getAccountNo(), complaint.getComplaintId())) {
				throw new BadDaoCallException ("Complaints with same id already exists!");
		} else {
			data.add(complaint.serialised());
			try {
				DbUtil.saveDb(FILE_PATH, data);
			} catch (BadDbCallException e) {
				throw new BadDaoCallException ("Unable to save complaints to db. " +e.getMessage());
			}
		}
	}
		
	private boolean ComplaintExist(String accountNo, String complaintId){
		for(int i=0;i<data.size();i++){
			CustomerComplaintVO complaint = new CustomerComplaintVO();
			try {
				complaint.setParameters(data.get(i));
				if (complaint.getAccountNo().equals(accountNo) && complaint.getComplaintId().equals(complaintId)) {
					return true;
				}
			} catch (InvalidParamsException e) {
				// ignore invalid entry
				e.printStackTrace();
			}
		}
		return false;
	}
	
	private void setComplaintStatus(String accountNo, String complaintId, String status) throws BadDaoCallException {
		for(int i=0;i<data.size();i++){
			CustomerComplaintVO complaint = new CustomerComplaintVO();
			try {
				complaint.setParameters(data.get(i));
				if (complaint.getAccountNo().equals(accountNo) && complaint.getComplaintId().equals(complaintId)) {
					complaint.setStatus(status);
					complaint.setDateModified(Util.getSystemDate());
					data.set(i, complaint.serialised());
					try {
						DbUtil.saveDb(FILE_PATH, data);
					} catch (BadDbCallException e1) {
						throw new BadDaoCallException ("Unable to save to db. " + e1.getMessage());
					}
				}
			} catch (InvalidParamsException e) {
				throw new BadDaoCallException ("Database entry corrupted. " + e.getMessage());
			}
		}
	}
	
	private CustomerComplaintVO getComplaint(String accountNo, String complaintId) {
		for(int i=0;i<data.size();i++){
			CustomerComplaintVO complaint = new CustomerComplaintVO();
			try {
				complaint.setParameters(data.get(i));
				if (complaint.getAccountNo().equals(accountNo) && complaint.getComplaintId().equals(complaintId)) {
					return complaint;
				}
			} catch (InvalidParamsException e) {
				// ignore invalid entry
				e.printStackTrace();
			}
		}
		return null;
	}
	
	private List<CustomerComplaintVO> getComplaints(String accountNo) {
		ArrayList<CustomerComplaintVO> results = new ArrayList<CustomerComplaintVO>();
		for(int i=0;i<data.size();i++){
			CustomerComplaintVO complaint = new CustomerComplaintVO();
			try {
				complaint.setParameters(data.get(i));
				if (complaint.getAccountNo().equals(accountNo)) {
					results.add(complaint);
				}
			} catch (InvalidParamsException e) {
				// ignore invalid entry
				e.printStackTrace();
			}
		}
		return results;
	}

	@Override
	public void  create(CustomerComplaintVO c) throws BadDaoCallException {
		CreateComplaint(c);
	}

	@Override
	public int changeComplatintStatus(String accNo, String cId) {
		try {
			setComplaintStatus(accNo, cId, sg.edu.nus.iss.billing.common.Util.COMPLAINT_CLOSED);
		} catch (BadDaoCallException e) {
			// Some error
			e.printStackTrace();
			return 0;
		}
		return 1;
	}

	@Override
	public CustomerComplaintVO findComplaintById(String accNo, String cmptId) {
		return getComplaint( accNo, cmptId);
	}

	@Override
	public List<CustomerComplaintVO> findAllComplaintsByAccountId(String accId) {
		return getComplaints(accId);
	}
	
	public void test() {
		// AA-0000-00-01^COMP-843-4cce-b43c-9dea27807043^pending^Sat Mar 31 16:38:25 SGT 2012^Sat Mar 31 16:38:25 SGT 2012^Allammma .. what do u do?
		String accountNo = "ACCT" + Util.generateRandomNumer();
		String complaintId = "C" + Util.generateRandomNumer();
		Date dateCreated = Util.getSystemDate();
		Date dateModified = Util.getSystemDate();
		String status = Util.COMPLAINT_PENDING;
		String content = "Just Complaining";
		CustomerComplaintVO complaint = new CustomerComplaintVO();
		complaint.setAccountNo(accountNo);
		complaint.setComplaintId(complaintId);
		complaint.setDateCreated(dateCreated);
		complaint.setDateModified(dateModified);
		complaint.setStatus(status);
		complaint.setComplaint(content);
		// create 
		System.out.println("Create Complaints");
		try {
			CreateComplaint(complaint);
		} catch (BadDaoCallException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		DbUtil.printDb(data);
		// update
		System.out.println("Update Complaints");
		try {
			setComplaintStatus(accountNo, complaintId, Util.COMPLAINT_CLOSED);
		} catch (BadDaoCallException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		DbUtil.printDb(data);
		// find
		System.out.println("Find Complaints");
		ArrayList<CustomerComplaintVO> list = (ArrayList<CustomerComplaintVO>) getComplaints(accountNo);
		for (int i=0; i<list.size(); i++) {
			System.out.println(list.get(i).serialised());
		}
		
	}

}
